package ports

import (
	"fmt"
	"net"
	"time"

	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
	"github.com/bujia-iot/iot-zinx/internal/infrastructure/config"
	"github.com/bujia-iot/iot-zinx/internal/infrastructure/logger"
	"github.com/bujia-iot/iot-zinx/internal/infrastructure/zinx_server/handlers"
	"github.com/bujia-iot/iot-zinx/pkg"
	"github.com/bujia-iot/iot-zinx/pkg/core"
	"github.com/bujia-iot/iot-zinx/pkg/network"
)

// TCPServer 封装TCP服务器功能
type TCPServer struct {
	server           ziface.IServer    // Zinx服务器实例
	cfg              *config.Config    // 配置文件实例
	heartbeatManager *HeartbeatManager // HeartbeatManager 心跳管理器实例
}

// NewTCPServer 创建新的TCP服务器实例
func NewTCPServer() *TCPServer {
	return &TCPServer{
		cfg: config.GetConfig(),
	}
}

// StartTCPServer 配置并启动Zinx TCP服务器
func StartTCPServer() error {
	server := NewTCPServer()
	return server.Start()
}

// Start 启动TCP服务器
func (s *TCPServer) Start() error {
	// 初始化服务器配置
	if err := s.initialize(); err != nil {
		return err
	}

	// 启动心跳管理器 - 必须在其他组件之前启动
	s.startHeartbeatManager()

	// 🚀 启动优先级2和3的定期清理任务
	s.startMaintenanceTasks()

	// 注册路由 - 核心指令流程
	s.registerRoutes()

	// 设置连接钩子 - 核心连接管理（在依赖初始化完成后）
	s.setupConnectionHooks()

	// 在启动Zinx服务前对齐TCPManager心跳超时配置，确保API在线判定一致
	if tm := core.GetGlobalTCPManager(); tm != nil {
		tm.SetHeartbeatTimeout(time.Duration(s.cfg.DeviceConnection.HeartbeatTimeoutSeconds) * time.Second)
	}

	// 配置一致性告警（仅日志提示，不阻塞）
	if s.cfg.TCPServer.DefaultReadDeadlineSeconds > 0 && s.cfg.DeviceConnection.HeartbeatTimeoutSeconds > 0 {
		if s.cfg.TCPServer.DefaultReadDeadlineSeconds < 120 {
			logger.Warnf("DefaultReadDeadlineSeconds=%ds 可能过小，易误判读超时", s.cfg.TCPServer.DefaultReadDeadlineSeconds)
		}
		if s.cfg.DeviceConnection.HeartbeatTimeoutSeconds < s.cfg.TCPServer.DefaultReadDeadlineSeconds {
			logger.Warnf("HeartbeatTimeoutSeconds(%ds) 小于 ReadDeadline(%ds)，请确认是否预期", s.cfg.DeviceConnection.HeartbeatTimeoutSeconds, s.cfg.TCPServer.DefaultReadDeadlineSeconds)
		}
	}
	if s.cfg.TCPServer.KeepAlive && s.cfg.TCPServer.KeepAlivePeriodSeconds <= 0 {
		logger.Warn("keepAlive 已启用但 keepAlivePeriodSeconds<=0，将采用默认15秒")
	}

	// 新架构：DeviceGateway统一管理TCP连接，无需单独的API适配器
	logger.Info("✅ TCP服务器使用DeviceGateway统一架构")

	// 启动服务器
	return s.startServer()
}

// initialize 初始化服务器配置
func (s *TCPServer) initialize() error {
	// 记录启动信息
	zinxCfg := s.cfg.TCPServer.Zinx

	// 设置Zinx服务器配置
	zconf.GlobalObject.Name = zinxCfg.Name
	zconf.GlobalObject.Host = s.cfg.TCPServer.Host
	zconf.GlobalObject.TCPPort = s.cfg.TCPServer.Port // 使用主配置的端口
	zconf.GlobalObject.Version = zinxCfg.Version
	zconf.GlobalObject.MaxConn = zinxCfg.MaxConn
	zconf.GlobalObject.MaxPacketSize = uint32(zinxCfg.MaxPacketSize)
	zconf.GlobalObject.WorkerPoolSize = uint32(zinxCfg.WorkerPoolSize)
	zconf.GlobalObject.MaxWorkerTaskLen = uint32(zinxCfg.MaxWorkerTaskLen)

	// 创建服务器实例
	s.server = znet.NewUserConfServer(zconf.GlobalObject)
	if s.server == nil {
		errMsg := "创建Zinx服务器实例失败"
		fmt.Printf("❌ %s\n", errMsg)
		logger.Error(errMsg)
		return fmt.Errorf("%s", errMsg)
	}

	// 创建DNY协议解码器并设置到服务器
	dnyDecoder := pkg.Protocol.NewDNYDecoder()
	if dnyDecoder == nil {
		errMsg := "创建DNY协议解码器失败"
		fmt.Printf("❌ %s\n", errMsg)
		logger.Error(errMsg)
		return fmt.Errorf("%s", errMsg)
	}
	s.server.SetDecoder(dnyDecoder)

	return nil
}

// registerRoutes 注册路由
func (s *TCPServer) registerRoutes() {
	handlers.RegisterRouters(s.server)
}

// setupConnectionHooks 设置连接钩子
func (s *TCPServer) setupConnectionHooks() {
	// 简化：直接设置连接回调
	s.server.SetOnConnStart(func(conn ziface.IConnection) {
		// 连接建立时的处理
		tcpManager := core.GetGlobalTCPManager()
		if tcpManager != nil {
			tcpManager.RegisterConnection(conn)
		}

		// 应用 TCP Keep-Alive 与 NoDelay 设置
		remote := ""
		if raw := conn.GetTCPConnection(); raw != nil {
			remote = raw.RemoteAddr().String()
			if tcpConn, ok := raw.(*net.TCPConn); ok {
				// KeepAlive
				if s.cfg.TCPServer.KeepAlive {
					_ = tcpConn.SetKeepAlive(true)
					period := s.cfg.TCPServer.KeepAlivePeriodSeconds
					if period <= 0 {
						period = 15
					}
					_ = tcpConn.SetKeepAlivePeriod(time.Duration(period) * time.Second)
				}
				// NoDelay
				_ = tcpConn.SetNoDelay(s.cfg.TCPServer.TCPNoDelay)

				logger.WithFields(map[string]interface{}{
					"connID":     conn.GetConnID(),
					"remoteAddr": remote,
					"keepAlive":  s.cfg.TCPServer.KeepAlive,
					"kaPeriod":   s.cfg.TCPServer.KeepAlivePeriodSeconds,
					"tcpNoDelay": s.cfg.TCPServer.TCPNoDelay,
				}).Info("TCP连接参数已应用")
			}
		}

		// 记录通信日志：连接开始
		if tcpConn := conn.GetTCPConnection(); tcpConn != nil {
			remote = tcpConn.RemoteAddr().String()
		}
		logger.LogCommunication("CONN_START", map[string]interface{}{
			"connID":     conn.GetConnID(),
			"remoteAddr": remote,
		}, "连接建立")
	})

	s.server.SetOnConnStop(func(conn ziface.IConnection) {
		// 连接关闭时的处理
		tcpManager := core.GetGlobalTCPManager()
		if tcpManager != nil {
			tcpManager.UnregisterConnection(conn.GetConnID())
		}

		// 记录通信日志：连接关闭
		remote := ""
		if tcpConn := conn.GetTCPConnection(); tcpConn != nil {
			remote = tcpConn.RemoteAddr().String()
		}
		logger.LogCommunication("CONN_STOP", map[string]interface{}{
			"connID":     conn.GetConnID(),
			"remoteAddr": remote,
		}, "连接关闭")
	})
}

// startHeartbeatManager 启动心跳管理器
func (s *TCPServer) startHeartbeatManager() {
	// 从配置中获取心跳间隔时间
	heartbeatInterval := time.Duration(s.cfg.DeviceConnection.HeartbeatIntervalSeconds) * time.Second
	heartbeatTimeout := time.Duration(s.cfg.DeviceConnection.HeartbeatTimeoutSeconds) * time.Second

	logger.Info("开始初始化心跳管理器")

	// 初始化自定义心跳管理器
	s.heartbeatManager = NewHeartbeatManager(heartbeatInterval, heartbeatTimeout)

	// 验证心跳管理器初始化
	if !s.heartbeatManager.IsInitialized() {
		logger.Fatal("❌ 心跳管理器初始化失败，服务器无法启动")
		return
	}

	logger.Info("✅ 心跳管理器实例创建成功")

	// 安全设置全局活动更新器
	if err := network.SetGlobalActivityUpdater(s.heartbeatManager); err != nil {
		logger.Fatal("❌ GlobalActivityUpdater设置失败")
		return
	}

	// 验证全局设置是否成功
	if !network.IsGlobalActivityUpdaterSet() {
		logger.Fatal("❌ GlobalActivityUpdater验证失败，服务器无法启动")
		return
	}

	logger.Info("✅ GlobalActivityUpdater设置成功")

	// 验证启动后状态
	logger.Info("✅ 自定义心跳管理器已成功启动并注入全局")

	// 调用诊断函数验证全局状态
	network.DiagnoseGlobalActivityUpdater()
}

// startMaintenanceTasks 启动维护任务（优先级2和3的定期清理）
func (s *TCPServer) startMaintenanceTasks() {
	// 🚀 优先级2：启动设备注册状态清理任务
	go s.startRegistrationCleanupTask()

	logger.Info("✅ 维护任务已启动（注册状态清理 + 连接健康清理）")
}

// startRegistrationCleanupTask 启动设备注册状态清理任务
func (s *TCPServer) startRegistrationCleanupTask() {
	ticker := time.NewTicker(30 * time.Minute) // 每30分钟清理一次
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			// 获取设备注册处理器并执行清理
			if handler := s.getDeviceRegisterHandler(); handler != nil {
				handler.CleanupExpiredStates()
			}
		}
	}
}

// getDeviceRegisterHandler 获取设备注册处理器实例
func (s *TCPServer) getDeviceRegisterHandler() interface {
	CleanupExpiredStates()
} {
	// 这里需要实现获取处理器的逻辑
	// 由于处理器是注册到路由中的，我们可能需要通过其他方式访问
	// 为了简化，我们直接创建一个新实例来执行清理
	return &handlers.DeviceRegisterHandler{}
}

// startServer 启动服务器并等待
func (s *TCPServer) startServer() error {
	// 添加错误捕获
	defer func() {
		if r := recover(); r != nil {
			errMsg := fmt.Sprintf("TCP服务器启动过程中发生panic: %v", r)
			fmt.Printf("❌ %s\n", errMsg)
			logger.Error(errMsg)
		}
	}()

	// 在单独的goroutine中启动服务器
	startChan := make(chan error, 1)
	go func() {
		defer func() {
			if r := recover(); r != nil {
				startChan <- fmt.Errorf("服务器启动panic: %v", r)
			}
		}()

		logger.Infof("TCP服务器启动在 %s:%d", s.cfg.TCPServer.Host, s.cfg.TCPServer.Port)
		s.server.Serve() // 阻塞调用
		startChan <- fmt.Errorf("服务器意外停止")
	}()

	// 等待启动结果或超时
	select {
	case err := <-startChan:
		errMsg := fmt.Sprintf("TCP服务器启动失败: %v", err)
		fmt.Printf("❌ %s\n", errMsg)
		logger.Error(errMsg)
		return err
	case <-time.After(2 * time.Second):
		// 2秒后如果没有错误，认为启动成功
		logger.Info("TCP服务器启动成功")
		select {} // 永远阻塞
	}
}
